package gold.digger;

import java.util.*;

/**
 * Created by fanzhenyu02 on 2020/6/27.
 * common problem solver template.
 */
public class LC1223 {
    public long startExecuteTime = System.currentTimeMillis();


    class Solution {
        public Map<String, Integer> memo = new HashMap<>();
        public static final int factor = 1000000000 + 7;

        public int dieSimulator(int n, int[] rollMax) {
            return dfs(n, rollMax, 0, 0);
        }

        public int dfs(int n, int[] rollMax, int lastChoiceSuccessiveRepeatCount, int lastChoiceNum) {
            if (n <= 1) return lastChoiceSuccessiveRepeatCount >= rollMax[lastChoiceNum - 1] ? 5 : 6;
            String key = n + "_" + lastChoiceSuccessiveRepeatCount + "_" + lastChoiceNum;
            if (memo.containsKey(key)) return memo.get(key);

            int solutionCount = 0, curChoiceSuccessiveRepeatCount = lastChoiceSuccessiveRepeatCount;
            for (int i = 1; i <= 6; i++) {
                if (i == lastChoiceNum) curChoiceSuccessiveRepeatCount = lastChoiceSuccessiveRepeatCount + 1;
                else curChoiceSuccessiveRepeatCount = 1;
                if (curChoiceSuccessiveRepeatCount > rollMax[i - 1]) continue;
                solutionCount += (dfs(n - 1, rollMax, curChoiceSuccessiveRepeatCount, i) % factor);
                solutionCount %= factor;
            }

            memo.put(key, solutionCount);
            return solutionCount;
        }
    }

    public void run() {
        Solution solution = new Solution();
//        输入：n = 2, rollMax = [1,1,2,2,2,3]
//        输出：34
//        输入：n = 2, rollMax = [1,1,1,1,1,1]
//        输出：30
//        输入：n = 3, rollMax = [1,1,1,2,2,3]
//        输出：181
//        int[] arr = {2, 1, 1, 3, 3, 2}; // 4
        int[] arr = {2, 1, 1, 3, 3, 2};
        System.out.println(solution.dieSimulator(4, arr));
    }

    public static void main(String[] args) throws Exception {
        LC1223 an = new LC1223();
        an.run();

        System.out.println("\ncurrent solution total execute time: " + (System.currentTimeMillis() - an.startExecuteTime) + " ms.");
    }
}
